{********************************************************************}
{                                                                    }
{           Developer Express Visual Component Library               }
{           Express Cross Platform Library classes                   }
{                                                                    }
{           Copyright (c) 2000-2014 Developer Express Inc.           }
{           ALL RIGHTS RESERVED                                      }
{                                                                    }
{   The entire contents of this file is protected by U.S. and        }
{   International Copyright Laws. Unauthorized reproduction,         }
{   reverse-engineering, and distribution of all or any portion of   }
{   the code contained in this file is strictly prohibited and may   }
{   result in severe civil and criminal penalties and will be        }
{   prosecuted to the maximum extent possible under the law.         }
{                                                                    }
{   RESTRICTIONS                                                     }
{                                                                    }
{   THIS SOURCE CODE AND ALL RESULTING INTERMEDIATE FILES            }
{   (DCU, OBJ, DLL, ETC.) ARE CONFIDENTIAL AND PROPRIETARY TRADE     }
{   SECRETS OF DEVELOPER EXPRESS INC. THE REGISTERED DEVELOPER IS    }
{   LICENSED TO DISTRIBUTE THE EXPRESSCROSSPLATFORMLIBRARY AND ALL   }
{   ACCOMPANYING VCL CONTROLS AS PART OF AN EXECUTABLE PROGRAM       }
{   ONLY.                                                            }
{                                                                    }
{   THE SOURCE CODE CONTAINED WITHIN THIS FILE AND ALL RELATED       }
{   FILES OR ANY PORTION OF ITS CONTENTS SHALL AT NO TIME BE         }
{   COPIED, TRANSFERRED, SOLD, DISTRIBUTED, OR OTHERWISE MADE        }
{   AVAILABLE TO OTHER INDIVIDUALS WITHOUT EXPRESS WRITTEN CONSENT   }
{   AND PERMISSION FROM DEVELOPER EXPRESS INC.                       }
{                                                                    }
{   CONSULT THE END USER LICENSE AGREEMENT FOR INFORMATION ON        }
{   ADDITIONAL RESTRICTIONS.                                         }
{                                                                    }
{********************************************************************}

unit dxIconLibrary;

{$I cxVer.inc}

interface

uses
  Classes, SysUtils, Controls, cxClasses, dxCore, cxGraphics,
  cxGeometry, dxGDIPlusClasses;

type
  TdxIconLibraryCustomObject = class;

  TdxIconLibraryItemClass = class of TdxIconLibraryCustomObject;

  { TdxIconLibraryCustomObject }

  TdxIconLibraryCustomObject = class
  private
    FName: string;
  public
    constructor Create(const AName: string); virtual;

    property Name: string read FName write FName;
  end;

  { TdxIconLibraryObjectList }

  TdxIconLibraryObjectList = class(TcxObjectList)
  private
    function GetItem(AIndex: Integer): TdxIconLibraryCustomObject;
  public
    function Add(AClass: TdxIconLibraryItemClass; const AName: string): TdxIconLibraryCustomObject;
    procedure SortByName; virtual;

    property Items[Index: Integer]: TdxIconLibraryCustomObject read GetItem; default;
  end;

  { TdxIconLibraryCustomGroup }

  TdxIconLibraryCustomGroup = class(TdxIconLibraryCustomObject)
  private
    FItems: TdxIconLibraryObjectList;

    function GetItem(AIndex: Integer): TdxIconLibraryCustomObject;
    function IsDirectory(const ASearchRec: TSearchRec): Boolean;
  protected
    procedure AddItem(const APath: string; const ASearchRec: TSearchRec); virtual; abstract;
    function GetCount: Integer; virtual;
  public
    constructor Create(const AName: string); override;
    destructor Destroy; override;
    procedure LoadFromDirectory(const APath: string); virtual;

    property Count: Integer read GetCount;
    property Items[Index: Integer]: TdxIconLibraryCustomObject read GetItem;
  end;

  { TdxIconLibraryImage }

  TdxIconLibraryImage = class(TdxIconLibraryCustomObject)
  private
    FFullFileName: string;
    FImage: TdxSmartImage;
    FTag: TdxNativeInt;

    function GetHeight: Integer;
    function GetWidth: Integer;
  public
    constructor Create(const AName: string); override;
    destructor Destroy; override;

    function SizeToText: string;

    property FullFileName: string read FFullFileName;
    property Height: Integer read GetHeight;
    property Image: TdxSmartImage read FImage;
    property Tag: TdxNativeInt read FTag write FTag;
    property Width: Integer read GetWidth;
  end;

  { TdxIconLibraryCategories }

  TdxIconLibraryCategories = class(TdxIconLibraryCustomGroup)
  private
    function GetItem(AIndex: Integer): TdxIconLibraryImage;
  protected
    procedure AddItem(const APath: string; const ASearchRec: TSearchRec); override;
  public
    property Items[Index: Integer]: TdxIconLibraryImage read GetItem;
  end;

  { TdxIconLibraryCollection }

  TdxIconLibraryCollection = class(TdxIconLibraryCustomGroup)
  private
    function GetItem(AIndex: Integer): TdxIconLibraryCategories;
  protected
    procedure AddItem(const APath: string; const ASearchRec: TSearchRec); override;
  public
    property Items[Index: Integer]: TdxIconLibraryCategories read GetItem;
  end;

  { TdxIconLibrary }

  TdxIconLibrary = class(TdxIconLibraryCustomGroup)
  private
    function GetItem(AIndex: Integer): TdxIconLibraryCollection;
  protected
    procedure AddItem(const APath: string; const ASearchRec: TSearchRec); override;
  public
    constructor Create(const AName: string); override;
    property Items[Index: Integer]: TdxIconLibraryCollection read GetItem;
  end;

implementation

function SortGroupItems(Item1, Item2: TdxIconLibraryCustomObject): Integer;
begin
  Result := CompareStr(Item1.Name, Item2.Name);
end;

{ TdxIconLibraryCustomObject }

constructor TdxIconLibraryCustomObject.Create(const AName: string);
begin
  FName := AName;
end;

{ TdxIconLibraryObjectList }

function TdxIconLibraryObjectList.Add(AClass: TdxIconLibraryItemClass; const AName: string): TdxIconLibraryCustomObject;
begin
  Result := AClass.Create(AName);
  inherited Add(Result);
end;

procedure TdxIconLibraryObjectList.SortByName;
begin
  Sort(@SortGroupItems);
end;

function TdxIconLibraryObjectList.GetItem(AIndex: Integer): TdxIconLibraryCustomObject;
begin
  Result := TdxIconLibraryCustomObject(inherited Items[AIndex]);
end;

{ TdxIconLibraryCustomGroup }

constructor TdxIconLibraryCustomGroup.Create(const AName: String);
begin
  inherited Create(AName);
  FItems := TdxIconLibraryObjectList.Create;
end;

destructor TdxIconLibraryCustomGroup.Destroy;
begin
  FreeAndNil(FItems);
  inherited Destroy;
end;

procedure TdxIconLibraryCustomGroup.LoadFromDirectory(const APath: string);
var
  ASearchRec: TSearchRec;
  AFindRes: Integer;
begin
  AFindRes := FindFirst(APath + '*.*', faDirectory or faAnyFile, ASearchRec);
  while AFindRes = 0 do
  begin
    AddItem(APath, ASearchRec);
    AFindRes := FindNext(ASearchRec);
  end;
  FindClose(ASearchRec);
  FItems.SortByName;
end;

function TdxIconLibraryCustomGroup.GetCount: Integer;
begin
  Result := FItems.Count;
end;

function TdxIconLibraryCustomGroup.GetItem(AIndex: Integer): TdxIconLibraryCustomObject;
begin
  Result := FItems[AIndex];
end;

function TdxIconLibraryCustomGroup.IsDirectory(const ASearchRec: TSearchRec): Boolean;
begin
  Result := ((ASearchRec.Attr and faDirectory) = faDirectory) and
    (ASearchRec.Name <> '.') and (ASearchRec.Name <> '..');
end;

{ TdxIconLibraryImage }

constructor TdxIconLibraryImage.Create(const AName: string);
begin
  inherited Create(ExtractFileName(AName));
  FFullFileName := AName;
  FImage := TdxSmartImage.Create;
  FImage.LoadFromFile(AName);
end;

destructor TdxIconLibraryImage.Destroy;
begin
  FreeAndNil(FImage);
  inherited Destroy;
end;

function TdxIconLibraryImage.SizeToText: string;
begin
  Result := IntToStr(Width) + 'x' + IntToStr(Height);
end;

function TdxIconLibraryImage.GetHeight: Integer;
begin
  Result := Image.Height;
end;

function TdxIconLibraryImage.GetWidth: Integer;
begin
  Result := Image.Width;
end;

{ TdxIconLibraryCategories }

procedure TdxIconLibraryCategories.AddItem(const APath: string; const ASearchRec: TSearchRec);
begin
  if IsDirectory(ASearchRec) then
    TdxIconLibraryCustomGroup(FItems.Add(
      TdxIconLibraryCategories, ASearchRec.Name)).LoadFromDirectory(APath + ASearchRec.Name + PathDelim)
  else
    if SameText(ExtractFileExt(ASearchRec.Name), '.png') then
      FItems.Add(TdxIconLibraryImage, APath + ASearchRec.Name);
end;

function TdxIconLibraryCategories.GetItem(AIndex: Integer): TdxIconLibraryImage;
begin
  Result := inherited GetItem(AIndex) as TdxIconLibraryImage;
end;

{ TdxIconLibraryCollection }

procedure TdxIconLibraryCollection.AddItem(const APath: string; const ASearchRec: TSearchRec);
begin
  if IsDirectory(ASearchRec) then
    TdxIconLibraryCustomGroup(FItems.Add(
      TdxIconLibraryCategories, ASearchRec.Name)).LoadFromDirectory(APath + ASearchRec.Name + PathDelim);
end;

function TdxIconLibraryCollection.GetItem(AIndex: Integer): TdxIconLibraryCategories;
begin
  Result := inherited GetItem(AIndex) as TdxIconLibraryCategories;
end;

{ TdxIconLibrary }

constructor TdxIconLibrary.Create(const AName: string);
begin
  inherited Create(AName);
  LoadFromDirectory(AName);
end;

procedure TdxIconLibrary.AddItem(const APath: string; const ASearchRec: TSearchRec);
begin
  if IsDirectory(ASearchRec) then
    TdxIconLibraryCustomGroup(FItems.Add(
      TdxIconLibraryCollection, ASearchRec.Name)).LoadFromDirectory(APath + ASearchRec.Name + PathDelim);
end;

function TdxIconLibrary.GetItem(AIndex: Integer): TdxIconLibraryCollection;
begin
  Result := inherited GetItem(AIndex) as TdxIconLibraryCollection
end;

end.
